package org.chen.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.chen.exception.ServiceException;
import org.chen.mapper.MovieTemplateMapper;
import org.chen.service.IMovieTemplateService;
import org.chen.template.MovieDetail;
import org.chen.template.MovieTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@Slf4j
public class MovieTemplateService extends ServiceImpl<MovieTemplateMapper,MovieTemplate> implements IMovieTemplateService {
    private static final String TEMPLATE_CACHE_KEY = "movie:template:";
    private static final long CACHE_EXPIRE_TIME = 24; // 24小时过期

    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    
    @Autowired
    private ObjectMapper objectMapper;

    // 系统启动时加载模板到缓存
    @PostConstruct
    public void initTemplatesCache() {
        try {
            List<MovieTemplate> templates = this.list(
                    new LambdaQueryWrapper<MovieTemplate>()
                            .eq(MovieTemplate::getIsEnabled, true)
            );
            for (MovieTemplate template : templates) {
                saveTemplateToCache(template);
            }
            log.info("模板缓存初始化完成，共加载{}个模板", templates.size());
        } catch (Exception e) {
            log.error("模板缓存初始化失败", e);
        }
    }

    // 保存模板到缓存
    private void saveTemplateToCache(MovieTemplate template) {
        try {
            redisTemplate.opsForValue().set(
                    TEMPLATE_CACHE_KEY + template.getId(),
                    template.getTemplateContent(),
                    CACHE_EXPIRE_TIME,
                    TimeUnit.HOURS
            );
        } catch (Exception e) {
            log.error("保存模板到缓存失败", e);
        }
    }

    // 从缓存删除模板
    private void removeTemplateFromCache(Long templateId) {
        try {
            redisTemplate.delete(TEMPLATE_CACHE_KEY + templateId);
        } catch (Exception e) {
            log.error("从缓存删除模板失败", e);
        }
    }

    // 获取所有启用的模板
    public List<MovieDetail> getAllEnabledTemplates() {
        try {
            // 确保只获取已启用的模板
            List<MovieTemplate> templates = this.list(
                    new LambdaQueryWrapper<MovieTemplate>()
                            .eq(MovieTemplate::getIsEnabled, true)
            );

            if (templates.isEmpty()) {
                throw new ServiceException("没有可用的模板，请先添加并启用模板");
            }

            List<MovieDetail> movieDetails = new ArrayList<>();
            for (MovieTemplate template : templates) {
                try {
                    MovieDetail detail = objectMapper.readValue(
                            template.getTemplateContent(),
                            MovieDetail.class
                    );
                    movieDetails.add(detail);
                } catch (Exception e) {
                    log.error("解析模板内容失败: {}", template.getId(), e);
                }
            }

            if (movieDetails.isEmpty()) {
                throw new ServiceException("没有有效的模板内容");
            }

            // 随机打乱模板顺序
            Collections.shuffle(movieDetails);

            return movieDetails;
        } catch (Exception e) {
            log.error("获取模板失败", e);
            throw new ServiceException("获取模板失败");
        }
    }

    // 添加模板
    @Transactional(rollbackFor = Exception.class)
    public void addTemplate(MovieTemplate template) {
        try {
            // 验证JSON格式
            objectMapper.readValue(template.getTemplateContent(), MovieDetail.class);

            template.setCreateTime(LocalDateTime.now());
            template.setUpdateTime(LocalDateTime.now());
            template.setIsEnabled(true);

            this.save(template);

            // 如果启用，则加入缓存
            if (template.getIsEnabled()) {
                saveTemplateToCache(template);
            }
        } catch (Exception e) {
            log.error("添加模板失败", e);
            throw new ServiceException("添加模板失败: " + e.getMessage());
        }
    }

    // 更新模板
    @Transactional(rollbackFor = Exception.class)
    public void updateTemplate(MovieTemplate template) {
        try {
            // 验证JSON格式
            objectMapper.readValue(template.getTemplateContent(), MovieDetail.class);

            template.setUpdateTime(LocalDateTime.now());
            this.updateById(template);

            // 更新缓存
            if (template.getIsEnabled()) {
                saveTemplateToCache(template);
            } else {
                removeTemplateFromCache(template.getId());
            }
        } catch (Exception e) {
            log.error("更新模板失败", e);
            throw new ServiceException("更新模板失败: " + e.getMessage());
        }
    }

    // 删除模板
    @Transactional(rollbackFor = Exception.class)
    public void deleteTemplate(Long templateId) {
        try {
            this.removeById(templateId);
            removeTemplateFromCache(templateId);
        } catch (Exception e) {
            log.error("删除模板失败", e);
            throw new ServiceException("删除模板失败: " + e.getMessage());
        }
    }

    // 启用/禁用模板
    @Transactional(rollbackFor = Exception.class)
    public void toggleTemplateStatus(Long templateId, Boolean enabled) {
        try {
            MovieTemplate template = this.getById(templateId);
            if (template == null) {
                throw new ServiceException("模板不存在");
            }

            template.setIsEnabled(enabled);
            template.setUpdateTime(LocalDateTime.now());
            this.updateById(template);

            if (enabled) {
                saveTemplateToCache(template);
            } else {
                removeTemplateFromCache(templateId);
            }
        } catch (Exception e) {
            log.error("更新模板状态失败", e);
            throw new ServiceException("更新模板状态失败: " + e.getMessage());
        }
    }

    // 分页查询模板
    public IPage<MovieTemplate> getTemplateList(Page<MovieTemplate> page, String templateName) {
        LambdaQueryWrapper<MovieTemplate> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.hasText(templateName)) {
            wrapper.like(MovieTemplate::getTemplateName, templateName);
        }
        wrapper.orderByDesc(MovieTemplate::getUpdateTime);

        return this.page(page, wrapper);
    }

    // 验证模板内容
    public boolean validateTemplateContent(String content) {
        try {
            objectMapper.readValue(content, MovieDetail.class);
            return true;
        } catch (Exception e) {
            log.error("模板内容格式验证失败", e);
            return false;
        }
    }

    // 批量删除模板
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchDeleteTemplates(List<Long> ids) {
        try {
            if (CollectionUtils.isEmpty(ids)) {
                throw new ServiceException("请选择要删除的模板");
            }

            // 查询要删除的所有模板
            List<MovieTemplate> templates = this.listByIds(ids);
            if (templates.isEmpty()) {
                return;
            }

            // 删除数据库记录
            this.removeByIds(ids);

            // 删除Redis缓存
            List<String> cacheKeys = templates.stream()
                    .map(template -> TEMPLATE_CACHE_KEY + template.getId())
                    .collect(Collectors.toList());
            redisTemplate.delete(cacheKeys);

            log.info("批量删除模板成功，ids: {}", ids);
        } catch (Exception e) {
            log.error("批量删除模板失败", e);
            throw new ServiceException("批量删除模板失败: " + e.getMessage());
        }
    }

    // 批量修改模板状态
    @Transactional(rollbackFor = Exception.class)
    public void batchToggleStatus(List<Long> ids, Boolean enabled) {
        try {
            if (CollectionUtils.isEmpty(ids)) {
                throw new ServiceException("请选择要操作的模板");
            }

            // 查询要修改的所有模板
            List<MovieTemplate> templates = this.listByIds(ids);
            if (templates.isEmpty()) {
                return;
            }

            // 批量更新状态
            LocalDateTime now = LocalDateTime.now();
            List<MovieTemplate> updateList = templates.stream()
                    .map(template -> {
                        template.setIsEnabled(enabled);
                        template.setUpdateTime(now);
                        return template;
                    })
                    .collect(Collectors.toList());

            // 批量更新数据库
            this.updateBatchById(updateList);

            // 处理缓存
            if (enabled) {
                // 如果是启用，则添加到缓存
                for (MovieTemplate template : templates) {
                    saveTemplateToCache(template);
                }
            } else {
                // 如果是禁用，则从缓存中删除
                List<String> cacheKeys = templates.stream()
                        .map(template -> TEMPLATE_CACHE_KEY + template.getId())
                        .collect(Collectors.toList());
                redisTemplate.delete(cacheKeys);
            }

            log.info("批量{}模板成功，ids: {}", enabled ? "启用" : "禁用", ids);
        } catch (Exception e) {
            log.error("批量{}模板失败", enabled ? "启用" : "禁用", e);
            throw new ServiceException("批量" + (enabled ? "启用" : "禁用") + "模板失败: " + e.getMessage());
        }
    }
}